---OOSE SoSe 2011 Aufgabe 3
--@author Oleg Mayevskiy <mayevskiy.oleg@googlemail.com> (233197)
require('gameClass')

Class{
'TicTacToe',Game,
	board = Table,
	boardSize = Number
}


function TicTacToe:printBoardNumeration()
	print(' --------')
	print('| 7 8 9  |')
	print('| 4 5 6  |')
	print('| 1 2 3  |')
	print(' --------')
end

function TicTacToe:init(pBoardSize)
	print('new Tic Tac Toe game initialized')
	self:printBoardNumeration()
	super:init()

	if(isNil(pBoardSize)) then
		self.boardSize = 3
	else
		self.boardSize = pBoardSize
	end

	self.board={}

	local initNr=1
	for i=1, self.boardSize do
		self.board[i]={}
		for j=1, self.boardSize do
			self.logger:finest('i = ',i,'j = ',j)
			--self.board[i][j] = initNr
			self.board[i][j] = ' '
			initNr = initNr + 1
		end
	end


	self.player1.name='X'
	self.player2.name='O'


end

function TicTacToe:print()
--7 8 9
--4 5 6
--1 2 3
	print(' --------		 --------')
	for i=self.boardSize,1,-1 do
		local currentRow='| '
		local rowNumbering=''
		for j =1,self.boardSize do
			self.logger:finest('i = ',i,'j = ',j)

			currentRow=currentRow..self.board[i][j]..' '
			rowNumbering=rowNumbering..((i-1)*self.boardSize+j)..' '
		end
		currentRow=currentRow..' |		| '..rowNumbering.. ' |'

		print(currentRow)
	end
	print(' --------		 --------')
end

function TicTacToe:doMove(nr)
	self.logger:fine('set nr: ', nr, 'to ',self.currentPlayer.name)


	local rowNr,columnNr = self:getBoardPosition(nr)

	self.board[rowNr][columnNr] = self.currentPlayer.name


	return self:otherPlayer()
end

function TicTacToe:getColumnNr(nr)
	return ((nr - 1) % self.boardSize) + 1
end

function TicTacToe:getRowNr(nr)
	return math.floor((nr-1)/3) + 1
end

function TicTacToe:getBoardPosition(nr)
	-- 1 1,1
	-- 2 1,2
	-- 3 1,3
	-- 4 2,1
	-- 5 2,2
	-- 6 2,3
	-- 7 3,1
	-- 8 3,2
	-- 9 3,3
	return self:getRowNr(nr), self:getColumnNr(nr)
end



--for tic tac toe move 0-9 is correct input for move method
function TicTacToe:checkMoveInput(nr)
	local isValid = isNumber(nr) and 0 <= nr and nr <=9
	if(not isValid) then
		print('expected 0-9, but your input was: ',nr)
	end
	return isValid
end

function TicTacToe:validateMove(nr)
	--self.logger:warning('TODO: validateMove must be implemented')

	if(not self:isFieldEmpty(nr)) then
		print('field',nr,'is allready filled, choose an other one')
		return false
	end


	return true
end

function TicTacToe:isFieldEmpty(nr)
	--return isNumber(self:getBoardValue(nr))
	return ' '==self:getBoardValue(nr)
end

function TicTacToe:isBoardFieldEmpty(rowNr, columnNr)
	return isNumber(self.board[rowNr][columnNr])
end

function TicTacToe:getBoardValue(nr)
	local rowNr,columnNr = self:getBoardPosition(nr)
	return self.board[rowNr][columnNr]
end

function TicTacToe:checkVictory(nr)
	local rowNr,columnNr = self:getBoardPosition(nr)


	--teste Spalte
	for i=1,self.boardSize do
		self.logger:finest('teste Spalte',i)
		if(self.board[rowNr][i] ~= self.currentPlayer.name) then
			break
		end
		if(i == self.boardSize) then
			return self.currentPlayer, true
		end
	end

	--teste Zeile
	for i=1,self.boardSize do
		self.logger:finest('teste zeile',i)
		if(self.board[i][columnNr] ~= self.currentPlayer.name) then
			break
		end
		if(i == self.boardSize) then
			return self.currentPlayer, true
		end
	end

	--teste Diagonale
	if(rowNr == columnNr) then
		self.logger:finest('teste diagonale')
		for i=1,self.boardSize do
			if(self.board[i][i] ~= self.currentPlayer.name) then
				break
			end
			if(i == self.boardSize) then
				return self.currentPlayer, true
			end
		end
	end

	--teste Anti-Diagonale
	self.logger:finest('teste diagonale')
	for i=1,self.boardSize do
		if(self.board[i][self.boardSize+1-i] ~= self.currentPlayer.name) then
			break
		end
		if(i == self.boardSize) then
			return self.currentPlayer, true
		end
	end





	--teste Unentschieden
	local emptyFieldsCount=self.boardSize * self.boardSize
	for i=1,self.boardSize * self.boardSize do
		if(self:isFieldEmpty(i)) then
			break
		end


		emptyFieldsCount = emptyFieldsCount - 1
		--alle Felder voll -> Unentschieden
		--nil = kein Gewinner
		if(0 == emptyFieldsCount) then
			return nil, true
		end
	end

	return nil, false


end

function TicTacToe:getPossibleTurns()
	local turns = {}
	for i=1, self.boardSize * self.boardSize do
		if(self:isFieldEmpty(i)) then
			table.insert(turns, i)
		end
	end
	return turns
end

function TicTacToe:printPossibleTurns()
	local output = 'Possible moves: '
	for i, v in ipairs(self:getPossibleTurns()) do
		output = output..v..' '
	end
	print(output)
end




